﻿namespace HuwmanCode

open System
open HuwmanCode
open HuwmanCode.IO
open NUnit.Framework
open FsUnit

type InterfaceA =
    abstract DoNothing: unit -> unit

type ImplementationOfInterfaceA =
    interface InterfaceA with
        member this.DoNothing () = ()

type InterfaceB<'T> =
    abstract DoSomething: 'T -> unit

type ImplementationOfInterfaceB<'T> =
    interface InterfaceB<'T> with
        member this.DoSomething x =
            ()

[<AbstractClass>]
type AbstractA =
    abstract DoSomething: int -> int
    default this.DoSomething (x) = x * x

type ImplementationOfAbstractA =
    inherit AbstractA

    override this.DoSomething x = x + x

[<TestFixture>]
type ``TypeExtension ``() =
    [<Test>]
    member this.``Type.IsImplementationOf - Type :> Interface = True``() =
        let baseType = typeof<InterfaceA>
        let specializedType = typeof<ImplementationOfInterfaceA>

        specializedType.IsImplementationOf (baseType) |> should be True

    [<Test>]
    member this.``Type.IsImplementationOf - Type<'T> :> Interface<'T> = True``() =
        let baseType = typeof<InterfaceB<int>>
        let specializedType = typeof<ImplementationOfInterfaceB<int>>

        specializedType.IsImplementationOf (baseType) |> should be True

    [<Test>]
    member this.``Type.IsImplementationOf - Type<'A> :> Interface<'B> = False``() =
        let baseType = typeof<InterfaceB<int>>
        let specializedType = typeof<ImplementationOfInterfaceB<string>>

        specializedType.IsImplementationOf (baseType) |> should be False

    [<Test>]
    member this.``Type.IsImplementationOf - Type :> AbstractType = True``() =
        let baseType = typeof<AbstractA>
        let specializedType = typeof<ImplementationOfAbstractA>

        specializedType.IsImplementationOf (baseType) |> should be True

